package org.dynamicallyacquired.controller;

import cn.hutool.core.lang.UUID;
import cn.soboys.restapispringbootstarter.Result;
import cn.soboys.restapispringbootstarter.annotation.Limit;
import cn.soboys.restapispringbootstarter.authorization.UserJwtToken;
import cn.soboys.restapispringbootstarter.enums.LogApiTypeEnum;
import cn.soboys.restapispringbootstarter.enums.LogCURDTypeEnum;
import cn.soboys.restapispringbootstarter.log.Log;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.dynamicallyacquired.domain.AndroidInfo;
import org.dynamicallyacquired.domain.DataPoint;
import org.dynamicallyacquired.request.HttpStatus;
import org.dynamicallyacquired.service.IAndroidInfoService;
import org.dynamicallyacquired.service.IDataPointService;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@Tag(name = "AndroidInfoController")
public class AndroidInfoController {

    @Resource
    private IAndroidInfoService androidInfoService;

    @Resource
    private IDataPointService dataPointService;

    @Resource
    KafkaTemplate<Object, Object> kafkaTemplate;

    @Resource
    private UserJwtToken userJwtToken;

    @PostMapping("/Upload_A_info")
    @Transactional(rollbackFor = RuntimeException.class)
    @Limit(key = "chat", name = "接口限流", period = 10, count = 3)
    @Log(value = "上传安卓Info", apiType = LogApiTypeEnum.USER, CURDType = LogCURDTypeEnum.RETRIEVE)
    public Result UploadAndroidInfo(@Validated @RequestBody AndroidInfo androidInfo) {
        AndroidInfo androidInfoByCode = androidInfoService.selectOne(new EntityWrapper<AndroidInfo>().eq("code", androidInfo.getCode()));
        if (androidInfoByCode != null) {
            if (!fieldsChanged(androidInfoByCode, androidInfo)) {
                // 如果没有变化，可以选择返回成功或相应的消息
                return Result.buildSuccess("No changes detected; operation successful.");
            }
            boolean appNameExists = androidInfoService.existsWithAppName(androidInfo.getAppName());
            if (!appNameExists ) {
                return Result.build(false, HttpStatus.INVALID_Android.getCode(), HttpStatus.INVALID_Android.getMessage(), "");
            }
            androidInfo.setUuid(androidInfoByCode.getUuid());
            String packageName = androidInfo.getPackageName();
            String[] parts = packageName.split("\\.");
            String lastWord = parts[parts.length - 1];
            androidInfo.setIconName(lastWord.trim().toLowerCase(Locale.ROOT));
            androidInfo.setId(androidInfoByCode.getId());
            System.out.println(androidInfo);
            boolean update = androidInfoService.updateById(androidInfo);
            if (update) {
                dataPointService.delete(new EntityWrapper<DataPoint>().eq("androidId", androidInfoByCode.getId()));
                Set<DataPoint> dataPoints = androidInfo.getDataPoints();
                List<DataPoint> dataPointList = dataPoints.stream().peek(dataPoint -> {
                    dataPoint.setAndroidId(androidInfo.getId());
                }).collect(Collectors.toList());
                dataPointService.insertBatch(dataPointList);
                kafkaTemplate.send("android_generate", androidInfoByCode.getUuid());
                return Result.buildSuccess("uuid-->" + androidInfoByCode.getUuid());
            } else {
                return Result.buildFailure(HttpStatus.REQUEST_TIMEOUT.getCode(), HttpStatus.REQUEST_TIMEOUT.getMessage());
            }
        } else {
            boolean b1 = androidInfoService.existsWithAppNameOrPackageName(androidInfo.getAppName(), androidInfo.getPackageName());
            AndroidInfo androidInfo1 = androidInfoService.selectOne(new EntityWrapper<AndroidInfo>().eq("packageName", androidInfo.getPackageName()).or().eq("appName",androidInfo.getAppName()));
            if (!b1) {
                if (!fieldsChanged(androidInfo1, androidInfo)) {
                    return Result.buildSuccess("No changes detected; operation successful.");
                }
                boolean appNameExists = androidInfoService.existsWithAppName(androidInfo.getAppName());
                if (!appNameExists ) {
                    return Result.build(false, HttpStatus.INVALID_Android.getCode(), HttpStatus.INVALID_Android.getMessage(), "");
                }
                androidInfo.setUuid(androidInfo1.getUuid());
                String packageName = androidInfo.getPackageName();
                String[] parts = packageName.split("\\.");
                String lastWord = parts[parts.length - 1];
                androidInfo.setIconName(lastWord.trim().toLowerCase(Locale.ROOT));
                androidInfo.setId(androidInfo1.getId());
                System.out.println(androidInfo);
                boolean update = androidInfoService.updateById(androidInfo);
                if (update) {
                    dataPointService.delete(new EntityWrapper<DataPoint>().eq("androidId", androidInfo1.getId()));
                    Set<DataPoint> dataPoints = androidInfo.getDataPoints();
                    List<DataPoint> dataPointList = dataPoints.stream().peek(dataPoint -> {
                        dataPoint.setAndroidId(androidInfo.getId());
                    }).collect(Collectors.toList());
                    dataPointService.insertBatch(dataPointList);
                    kafkaTemplate.send("android_generate", androidInfo1.getUuid());
                    return Result.buildSuccess("uuid-->" + androidInfo1.getUuid());
                } else {
                    return Result.buildFailure(HttpStatus.REQUEST_TIMEOUT.getCode(), HttpStatus.REQUEST_TIMEOUT.getMessage());
                }
            } else {
                String uniqueId = UUID.randomUUID().toString();
                androidInfo.setUuid(uniqueId);
                String packageName = androidInfo.getPackageName();
                String[] parts = packageName.split("\\.");
                String lastWord = parts[parts.length - 1];
                androidInfo.setIconName(lastWord.trim().toLowerCase(Locale.ROOT));
                System.out.println(androidInfo);
                boolean insert = androidInfoService.insert(androidInfo);
                if (insert) {
                    Set<DataPoint> dataPoints = androidInfo.getDataPoints();
                    List<DataPoint> dataPointList = dataPoints.stream().peek(dataPoint -> {
                        dataPoint.setAndroidId(androidInfo.getId());
                    }).collect(Collectors.toList());
                    boolean b = dataPointService.insertBatch(dataPointList);
                    if (b) {
                        kafkaTemplate.send("android_generate", uniqueId);
                    }
                    return Result.buildSuccess("uuid-->" + uniqueId);
                } else {
                    return Result.buildFailure(HttpStatus.REQUEST_TIMEOUT.getCode(), HttpStatus.REQUEST_TIMEOUT.getMessage());

                }
            }
        }
    }

    private boolean fieldsChanged(AndroidInfo existing, AndroidInfo submitted) {
        return !Objects.equals(existing.getAppName(), submitted.getAppName()) ||
                !Objects.equals(existing.getPackageName(), submitted.getPackageName()) ||
                !Objects.equals(existing.getUrl(),submitted.getUrl()) ||
                !Objects.equals(existing.getAdjust_token(),submitted.getAdjust_token()) ||
                !Objects.equals(existing.getAppsflyer_token(),submitted.getAppsflyer_token());
    }

    @GetMapping(value = {"/get_A_info"})
    @Transactional(rollbackFor = RuntimeException.class)
    public AndroidInfo getAndroidInfo(@RequestParam("uuid") @Validated String UUID) {
        AndroidInfo selectedInfo = androidInfoService.selectAndroidInfoWithPoints(UUID);
        System.out.println("打包时请求的数据：-->>" + selectedInfo);
        return selectedInfo;
    }

    @GetMapping("/generate")
    @Transactional(rollbackFor = RuntimeException.class)
    public Result generate(@RequestParam("userId") @Validated String userId) {
        userJwtToken.rememberMe = true;
//        String token = userJwtToken.createdToken(userId,);
        return Result.buildSuccess("token");
    }


}
